package mensch;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Game {
	
	private List<Player> players;
	private Table table;
	private Player leader;
	private int roundCounter = 1;
	private String opponentDiceValues = "";
	private int playerDiceValue = 1;
	private boolean inProgress = true;
	private boolean skipOpponent = false;
	private long startTime = System.currentTimeMillis();

	/**
	 * number of players. For UE2: 2
	 */
	private int numberOfPlayers = 2;
	
	public Game() {
		players = new ArrayList<Player>();
		players.add(new Player("Super Mario", 0));
		players.add(new Player("Computer", 1));
		players.add(new Player("Luigi", 2));
		players.add(new Player("Yoshi", 3));
		
		table = new Table(players);
		
		// by default player 1 is set as leader to keep it simple
		leader = players.get(0);
	}
	
	public List<Player> getPlayers() {
		return players;
	}
	
	public Table getTable() {
		return table;
	}
	
	public int getNumberOfPlayers() {
		return numberOfPlayers;
	}
	
	public String getActivePlayerName() {
		return players.get(0).getUsername();
	}
	
	public String getLeaderName() {
		return leader.getUsername();
	}
	
	public int getCurrentRound() {
		return roundCounter;
	}
	
	public String getOpponentDiceValues() {
		return opponentDiceValues;
	}
	
	public boolean isInProgress() {
		return inProgress;
	}
	
	public int getPlayerDiceValue() {
		return playerDiceValue;
	}
	
	public long getTime() {
		return System.currentTimeMillis() - startTime;
	}
	
	public void startTurn() {
		for (int activePlayerId = 0; activePlayerId < numberOfPlayers; activePlayerId++) {
			if (activePlayerId == 1 && skipOpponent) {
				skipOpponent = false;
				continue;
			}
			roll(activePlayerId);
		}
		roundCounter++;
	}
	
	private void roll(int activePlayerId) {
		int diceValue = rollDice();
		// int diceValue = 1; // Debug

		Player player = players.get(activePlayerId);
		Pawn pawn = player.getPawns().get(0);
		Field currentField = pawn.getField();
		int newFieldIndex;

		if (activePlayerId == 1) {
			if (opponentDiceValues.equals("")) {
				opponentDiceValues = Integer.toString(diceValue);
			} else {
				opponentDiceValues += " - " + diceValue;
			}
		} else {
			opponentDiceValues = "";
			playerDiceValue = diceValue;
		}

		// Im Starthaus
		if (currentField instanceof HomeField) {
			if (diceValue == 6) {
				newFieldIndex = player.getFirstFieldIndex();
				makeMove(pawn, newFieldIndex);
				pawn.incrementFieldCounter(1);
			}

			// nicht im Starthaus
		} else {
			int currentFieldIndex = currentField.getFieldIndex();
			newFieldIndex = currentFieldIndex + diceValue;

			if (newFieldIndex > 39) {
				newFieldIndex -= 40;
			}
			pawn.incrementFieldCounter(diceValue);

			int fieldCounter = pawn.getFieldCounter();
			if (fieldCounter <= 40) {
				makeMove(pawn, newFieldIndex);
			} else {
				int goalFieldCounter = fieldCounter - 40;
				if (goalFieldCounter <= 4) {
					int goalFieldIndex = player.getFirstGoalIndex()
							+ goalFieldCounter - 1;
					makeMove(pawn, goalFieldIndex);
					inProgress = false;
					// Spiel vorbei
				} else {
					// Ueberwuerfelt -> Kein Zug moeglich
				}
			}
		}

		// find out leader
		if (player.getProgress() > leader.getProgress()) {
			leader = player;
		}

		if (diceValue == 6) {
			if (activePlayerId == 1) {
				roll(activePlayerId);
			} else {
				skipOpponent = true;
			}
		}
	}
	
	private void makeMove(Pawn pawn, int newFieldIndex) {
		Field newField = table.getFields().get(newFieldIndex);
		
		// check if field is occupied
		if (newField.getPawnOnField() != null) {
			Pawn pawnOnField = newField.getPawnOnField();
			Player pawnOnFieldOwner = pawnOnField.getPlayer();
			Field homeField = table.getFields().get(pawnOnFieldOwner.getFirstHomeIndex());
			pawnOnField.moveTo(homeField);
			pawnOnField.resetCounter();
		}
		
		pawn.moveTo(newField);
	}
	
	private int rollDice() {
		return new Random().nextInt(6) + 1;
	}
}
